大数据Spark生态系统 修仙之道 Scala Blog

2019-05-01 Docs Language:简体中文 & English Programing Scala Website:www.geekparkhub.com OpenSource GitHub repo size in bytes GeekDeveloper:JEEP-711 Github:github.com/geekparkhub Gitee:gitee.com/geekparkhub

🐘 Scala Technology 修仙之道 炼精化炁 🐘

Alt text


0. 学习前你需要了解

在继续本教程之前,你应该了解一些基本计算机编程术语.

Spark是新一代基于内存级大数据计算框架,是大数据重要内容.

Spark是基于Scala编程语言构建完成,如果你学习过Java编程语言,将有助于你更快了解掌握Scala编程语言.

1. Scala 概述

Scala是一门多范式(multi-paradigm)编程语言,设计初衷是要集成面向对象编程和函数式编程各种特性.

Scala运行在Java虚拟机上,并兼容现有Java程序.

Scala源代码被编译成Java字节码,所以它可以运行于JVM之上,并可以调用现有Java类库.

Spark的兴起,带动了Scala语言的发展.

2. Scala 语言诞生

创始人马丁 · 奥德斯基(Martin Oderskv)是编译器及编程的狂热爱好者.

长时间的编程之后,希望发明一种语言,能够让写程序这样的基础工作变得高效,简单.

所以当接触到JAVA语言后,对JAVA这门便携式,运行在网络,且存在垃圾回收的语言产生了极大的兴趣,所以决定将函数式编程语言的特点融合到JAVA中.

由此发明了两种语言(Pizza & Scala) / Pizza 和 Scala极大地推动了JAVA编程语言的发展.
jdk5.0泛型,for循环增强,自动类型转换等,都是从Pizza,引入的新特性.

jdk8.0的类型推断,Lambda表达式就是从Scala引入的特性.

且现在主流JVM 的javac编译器就是马丁 · 奥德斯基编写出来的,Jdks5.0 & Jdk8.0的编辑器就是马丁 · 奥德斯基编写的,因此马丁 · 奥德斯基一个人的战斗力抵得上一个JAVA开发团队.

3. Scala 语言特点

Scala是一门以java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言.

Scala是一门多范式(multi-paradigm)的编程语言,Scala支持面向对象和函数式编程.

Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接.

Scala单作为一门语言来看,非常简洁高效(三元运算 / ++ / –).

Scala 在设计时,马丁·奥德斯基是参考了Java的设计思想,可以说Scala是源于java,同时马丁·奥德斯基也加入了自己的思想,将函数式编程语言的特点融合到JAVA中,因此,对于学习过Java的开发者,只要在学习Scala过程中,搞清楚Scala和java相同点和不同点,就可以快速的掌握Scala这门语言.

4. Scala 部署

4.1 MacOs 部署 Scala

systemhub:dev_package system$ pwd
/Users/system/home/work/develop/work_flow/software/dev_package
systemhub:dev_package system$ tar -zxvf scala-2.11.8.tgz -C /Users/system/home/work/develop/work_flow/module/
systemhub:work_flow system$ cd module/
systemhub:module system$ mv scala-2.11.8/ scala
systemhub:module system$ ls -ll
total 0
drwxr-xr-x 10 system staff 340 2 25 20:52 maven
drwxr-xr-x@ 17 system staff 578 5 9 11:46 tomcat
drwxr-xr-x 13 system staff 442 2 28 23:28 hadoop
drwxr-xr-x 6 system staff 204 3 4 2016 scala
systemhub:module system$
systemhub:module system$ cd scala/
systemhub:scala system$ pwd
/Users/system/home/work/develop/work_flow/module/scala
systemhub:scala system$ sudo vim /etc/profile
## SET SCALA_HOME
export SCALA_HOME=/Users/system/home/work/develop/work_flow/module/scala
export PATH=$PATH:$SCALA_HOME/bin
systemhub:scala system$ source /etc/profile
systemhub:scala system$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8).
Type in expressions for evaluation. Or try :help.
scala> print("Hello World!");
Hello World!
scala> :quit
systemhub:scala system$

4.2 Linux 部署 Scala

[root@systemhub511 software]# tar -zxvf scala-2.11.8.tgz -C /opt/module/
[root@systemhub511 module]# mv scala-2.11.8/ scala
[root@systemhub511 module]# ll
total 44
drwxr-xr-x. 9 root root 4096 Feb 24 21:55 tomcat
drwxr-xr-x. 3 root root 4096 May 12 16:12 cdh_flow
drwxr-xr-x. 3 root root 4096 May 20 22:46 datas
drwxr-xr-x. 10 root root 4096 Apr 11 17:02 flume
drwxr-xr-x. 3 root root 4096 May 8 20:55 HA
drwxr-xr-x. 12 10011 10011 4096 Mar 3 00:42 hadoop
drwxr-xr-x. 8 root root 4096 May 6 23:31 hbase
drwxr-xr-x. 8 uucp 143 4096 Dec 20 2017 jdk1.8
drwxr-xr-x. 8 root root 4096 Apr 17 14:15 kafka
drwxrwxr-x. 6 1001 1001 4096 Mar 4 2016 scala
drwxr-xr-x. 11 1001 1001 4096 Apr 17 13:31 zookeeper
[root@systemhub511 module]#
[root@systemhub511 module]# cd scala/
[root@systemhub511 scala]# pwd
/opt/module/scala
[root@systemhub511 scala]# vim /etc/profile
## SET SCALA_HOME
export SCALA_HOME=/opt/module/scala
export PATH=$PATH:$SCALA_HOME/bin
[root@systemhub511 scala]# source /etc/profile
[root@systemhub511 module]# scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8).
Type in expressions for evaluation. Or try :help.
scala> print("Hello World!");
Hello World!
scala> :quit
[root@systemhub511 bin]#

5. Scala 插件 For JetBrains IntelliJ IDEA

enter image description here

6. Scala Quick Start

package com.geekparkhub.core.scala.quickstart
/**
* Geek International Park | 极客国际公园
* GeekParkHub | 极客实验室
* Website | https://www.geekparkhub.com/
* Description | Open开放 · Creation创想 | OpenSource开放成就梦想 GeekParkHub共建前所未见
* HackerParkHub | 黑客公园枢纽
* Website | https://www.hackerparkhub.com/
* Description | 以无所畏惧的探索精神 开创未知技术与对技术的崇拜
* GeekDeveloper : JEEP-711
*
* @author system
* <p>
* QuickStartScala
* <p>
*/
object QuickStartScala {
def main(args: Array[String]): Unit = {
println("Scala ~ Hello World!");
}
}
Scala ~ Hello World!

enter image description here

6.1 反编译 Scala程序 执行流程

6.1.1 Java模拟Scala代码

package com.geekparkhub.core.scala.decompile;
/**
* Geek International Park | 极客国际公园
* GeekParkHub | 极客实验室
* Website | https://www.geekparkhub.com/
* Description | Open开放 · Creation创想 | OpenSource开放成就梦想 GeekParkHub共建前所未见
* HackerParkHub | 黑客公园枢纽
* Website | https://www.hackerparkhub.org/
* Description | 以无所畏惧的探索精神 开创未知技术与对技术的崇拜
* GeekDeveloper : JEEP-711
*
* @author system
* <p>
* QuickStartScala
*
* Scala 执行流程
* 1. object 在底层会生成两个类QuickStartScala,QuickStartScala$
* 2. `QuickStartScala`中有main函数,调用`QuickStartScala$` 类的一个静态对象 `MODULES$`
* <p>
*/
public final class QuickStartScala {
public static void main(String[] paramArrayOfString) {
// 3. QuickStartScala$.MODULE$. 对象是静态的,通过该对象调用QuickStartScala$的main函数
QuickStartScala$.MODULE$.main(paramArrayOfString);
}
}
final class QuickStartScala$ {
public static final QuickStartScala$ MODULE$;
static {
MODULE$ = new QuickStartScala$();
}
/**
* 可以理解为在main函数编写的代码放在QuickStartScala$的main函数中,其实是在底层执行scala编译器做了包装
* @param args
*/
public static void main(String[] args) {
System.out.println("Scala ~ Hello World!");
}
}

6.1.2 Scala执行流程

enter image description here

6.1.3 Scala程序 开发注意事项 (重点)

6.2 Scala 转义字符

6.3 Scala 语言输出方式

package com.geekparkhub.core.scala.demo
/**
* Geek International Park | 极客国际公园
* GeekParkHub | 极客实验室
* Website | https://www.geekparkhub.com/
* Description | Open开放 · Creation创想 | OpenSource开放成就梦想 GeekParkHub共建前所未见
* HackerParkHub | 黑客公园枢纽
* Website | https://www.hackerparkhub.org/
* Description | 以无所畏惧的探索精神 开创未知技术与对技术的崇拜
* GeekDeveloper : JEEP-711
*
* @author system
* <p>
* DemoTest
* <p>
*/
object DemoTest {
def main(args: Array[String]): Unit = {
/**
* String stitching output
* 字符串拼接 输出
*/
val parameter1: String = "Hello "
var parameter2: String = "World!"
println(parameter1 + parameter2)
/**
* Dividing line
* 分割线
*/
println(s"-----------------------------------------------------------------------------------------")
/**
* Printf formatted output
* printf格式化 输出
*/
var name: String = "TestUser001"
var age: Int = 66;
var investment: Float = 722.37f
var assets: Double = 777777777.158
printf("name is = %s | age is = %d | investment is = %.2f | assets is = %.3f", name, age, investment, assets)
/**
* Dividing line
* 分割线
*/
println(s"\n-----------------------------------------------------------------------------------------")
/**
* String + $ output
* 字符串+$ 输出
*/
println(s"Demo1 info : \n name is = $name \n age is = $age \n investment is = $investment \n assets is = $assets")
/**
* Dividing line
* 分割线
*/
println(s"-----------------------------------------------------------------------------------------")
/**
* Expression +$ output
* 表达式+$ 输出
*/
println(s"Demo2 info : \n name is = $name \n age is = $age \n investment is = ${investment + 10} \n assets is = ${assets * 20}")
}
}
Hello World!
-----------------------------------------------------------------------------------------
name is = TestUser001 | age is = 66 | investment is = 722.37 | assets is = 777777777.158
-----------------------------------------------------------------------------------------
Demo1 info :
name is = TestUser001
age is = 66
investment is = 722.37
assets is = 7.77777777158E8
-----------------------------------------------------------------------------------------
Demo2 info :
name is = TestUser001
age is = 66
investment is = 732.37
assets is = 1.555555554316E10

6.4 Scala 注释 (comment)

6.5 Scala 代码规范说明

/** Contains a fallback builder for arrays when the element type
* does not have a class tag. In that case a generic array is built.
*/
class FallbackArrayBuilding {
/** A builder factory that generates a generic array.
* Called instead of `Array.newBuilder` if the element type of an array
* does not have a class tag. Note that fallbackBuilder factory
* needs an implicit parameter (otherwise it would not be dominated in
* implicit search by `Array.canBuildFrom`). We make sure that
* implicit search is always successful.
*/
implicit def fallbackCanBuildFrom[T](implicit m: DummyImplicit): CanBuildFrom[Array[_], T, ArraySeq[T]] =
new CanBuildFrom[Array[_], T, ArraySeq[T]] {
def apply(from: Array[_]) = ArraySeq.newBuilder[T]
def apply() = ArraySeq.newBuilder[T]
}
}

6.6 Scala 官方API指南

Scala 官方API指南 : scala-lang.org/api/2.11.8

6.7 Scala 变量

变量使用基本步骤

Scala 变量基本使用

var age : Int = 10
var sal : Double = 10.9
var name : String = "tom"
var isPass : Boolean = true
var score : Float = 70.9f

Scala 变量使用说明

6.8 Scala 数据类型

6.8.1 Scala 数据类型体系

enter image description here

6.8.2 Scala 数据类型列表

数据类型 描述
Byte 8位有符号补码整数
Short 16位有符号补码整数
Int 32位有符号补码整数
Long 64位有符号补码整数
Float 32位标准单精度浮点数
Double 64位标准单精度浮点数
Char 16位无符号Unicode字符
String 字符序列
Boolean true / false
Unit 表示无值等同于void
Null null
Nothing 任何其他类型的子类型
Any 所有类的超类
AnyRef 引用类的基类

6.8.3 Scala 整形数据类型

数据类型 描述
Byte [1] 8位有符号补码整数,数值区间为-128到127
Short [2] 16位有符号补码整数,数值区间为-32768到32767
Int [4] 32位有符号补码整数,数值区间为-2147483648到2147483647
Long [8] 64位有符号补码整数,数值区间为-9223372036854775808到9223372036854775807=2的(64-1)次方-1

6.8.4 Scala 浮点数据类型

数据类型 描述
Float [4] 32位标准单精度浮点数
Double [8] 64位标准双精度浮点数

6.8.5 Scala (Char) 字符数据类型

6.8.6 Scala (Boolean) 布尔数据类型

6.8.7 Scala (Unit / Null / Nothing) 数据类型

数据类型 描述
Unit 表示无值等同于void
Null null,Null类型只有一个实例null
Nothing 任何其他类型的子类型

6.8.8 Scala 值类型转换

6.8.8.1 值类型隐式转换
6.8.8.2 高级隐式转换和隐式函数
6.8.8.3 强制类型转换
java : int num = (int)2.5
scala : var num : Int = 2.7.toInt //对象
object DemoTest002 {
def main(args: Array[String]): Unit = {
val num1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt
val num2: Int = (10 * 3.5 + 6 * 1.5).toInt
println(num1 +" - "+num2)
}
}
6.8.8.4 数据类型转换 实例
1. var s : Short = 5 //ok
s = s-2 //error Int -> Short
2. var b : Byte = 3 //ok
b = b + 4 // error Int ->Byte
b = (b+4).toByte // ok,使用强制转换
3. var c : Char = 'a' //ok
var i : Int = 5 //ok
var d : Float = .314F //ok
var result : Double = c+i+d //ok Float->Double
4. var b : Byte = 5 //ok
var s : Short = 3 //ok
var t : Short = s + b //error Int->Short
var t2 = s + b //ok,使用类型推导
6.8.8.5 值类型和String类型转换
// 基本类型转String类型
val d1 = 1.2
val s1 = d1 + ""
println(d1 +" ~ "+ s1)
// String类型转基本数据类型
val s2 = "11"
val int: Int = s2.toInt
val byte: Byte = s2.toByte
val double: Double = s2.toDouble
val long: Long = s2.toLong
println(s2 +" ~ "+ int +" ~ "+ byte +" ~ "+ double +" ~ "+ long)
6.8.8.6 标识符命名规范
6.8.8.6.1 标识符概念
6.8.8.6.2 标识符命名规则
6.8.8.6.3 标识符举例说明
// 首字符为操作符(比如+ -* /),后续字符也需跟操作符,至少一个
val ++ = "hello,scala"
println(++)
val -+*/ = 90
println(-+*/)
val `true` = "hello"
println(`true`)
6.8.8.6.4 标识符命名注意事项
6.8.8.6.5 Scala 39个关键字
package, import, class, object, trait, extends, with, type, forSome
private, protected, abstract, sealed, final, implicit, lazy, override
try, catch, finally, throw
if, else, match, case, do, while, for, return, yield
true, false, null
def, val, var
this, super
new

6.9 Scala 运算符

6.9.1 运算符介绍

6.9.2 算术运算符

运算符 运算 范例 结果
+ 正号 +1 1
- 负号 b=4; -b -4
+ 5+5 10
- 6-4 2
* 3*4 12
/ 5/5 1
% 取余 7%5 2
+ 字符串相加 “he”+”llo” “hello”
// 除法 算数运算使用
val r1: Int = 10 /3
val r2: Double = 10 /3
val r3: Double = 10.0 /3
println(r1 +" ~ "+ r2 +" ~ " + r3 + " ~ " +r3.formatted("%.2f"))
// 取余 算数运算使用 | 取余运算原则 : a % b = a - a/b * b
println(10 % 3)
println(10 % -3)
println(-10 % 3)
println(-10 % -3)

6.9.3 关系运算符 (比较运算符)

运算符 运算 范例 结果
== 相等于 4==3 false
!= 不等于 4!=3 true
< 小于 4<3 false
> 大于 4>3 true
<= 小于等于 4<=3 false
>= 大于等于 4>=3 true

6.9.4 逻辑运算符

运算符 运算 范例 结果
&& 逻辑与 (A&&B) false
逻辑或 (A或B) true
! 逻辑非 !(A&&B) true

6.9.5 赋值运算符

运算符 运算 范例 结果
= 将值赋给左值 C = A + B 将A+B结果赋值为C
+= 相加后再赋值 C += A C = C + A
-= 相减后再赋值 C -= A C = C - A
*= 相乘后再赋值 C *= A C = C * A
/= 相除后再赋值 C /= A C = C / A
%= 取余后再赋值 C %= A C = C % A
<<= 左移后再赋值 C <<= 2 C = C << 2
>>= 右移后再赋值 C >>= 2 C = C >> 2
&= 按位与再赋值 C $= 2 C = C & 2
^= 按位异或后再赋值 C ^= 2 C = C ^ 2
或= 按位或后再赋值 C 或= 2 C = C 或 2
运算符 运算 范例 结果
& 按位与运算符 (a&b) 结果12,二进制0000 1100
按位或与运算符 (a或b) 结果61,二进制0011 1101
^ 按位异或运算符 (a^b) 结果49,二进制0011 0001
~ 按位取反运算符 (~a) 结果-61,二进制1100 0011,在一个有符号二进制数的补码形式
<< 左移动运算符 a<<2 结果240,二进制1111 0000
>> 右移动运算符 a>>2 结果15,二进制0000 1111
>>> 无符号右移 A>>>2 结果,二进制0000 1111

6.9.6 运算符优先级

6.9.7 键盘输入语句

object DemoTest003 {
def main(args: Array[String]): Unit = {
println("Please type in your name")
val name = StdIn.readLine()
println("Please enter age")
val age = StdIn.readInt()
println("Please enter the height")
val height = StdIn.readDouble()
printf("Your input information is : name=%s age=%d height=%.2f", name, age, height)
}
}

6.10 Scala 程序流程控制

6.10.1 分支控制 if-else

6.10.1.1 单分支
if(条件表达式){
执行代码块
}
object DemoTest004 {
def main(args: Array[String]): Unit = {
println("Please enter age")
val age = StdIn.readInt()
if (age > 18) {
printf("age > " + age)
}
}
}
6.10.1.2 双分支
if (条件表达式) {
执行代码块1
} else {
执行代码块2
}
object DemoTest004 {
def main(args: Array[String]): Unit = {
val ages = 17
if (ages > 18) {
println(ages + " > 17")
} else {
println(ages + " < 17")
}
}
}
6.10.1.3 多分支
if (条件表达式1) {
执行代码块1
} else if (条件表达式2) {
执行代码块2
}
......
else {
执行代码块n
}
object DemoTest005 {
def main(args: Array[String]): Unit = {
while (true) {
println("------------")
println("请输入修仙等级")
println("------------")
val grade = StdIn.readInt()
if (grade == 100) {
println("+++++++")
println("登峰造极")
} else if (grade > 80 && grade <= 99) {
println("+++++++")
println("炉火纯青")
} else if (grade >= 60 && grade <= 80) {
println("+++++++")
println("热化提纯")
} else {
println("+++++++")
println("无名小卒")
}
}
}
}
6.10.1.4 分支控制if-else 注意事项

6.10.2 嵌套分支

if(){
if(){
} else {
}
}
object DemoTest006 {
def main(args: Array[String]): Unit = {
println("请输入你的年龄")
val age = StdIn.readInt()
if (age >= 18) {
println("你的年龄大于18岁,请输入你的性别")
val sex = StdIn.readChar()
if (sex == '男') {
println("已进入男子竞技频道")
} else {
println("已进入女子竞技频道")
}
} else {
println("你的年龄小于18岁,游戏结束")
}
}
}

6.10.3 switch 分支结构

6.10.4 for 循环控制

6.10.4.1 范围数据循环方式 1
for(i <-1 to 3){
print(i + " ")
}
object DemoTest007 {
def main(args: Array[String]): Unit = {
val start = 1
val end = 10
for (i <- start to end) {
println(i + " - hello")
}
}
}
6.10.4.2 范围数据循环方式 2
for(i <-1 until 3) {
print(i + " ")
}
object DemoTest007 {
def main(args: Array[String]): Unit = {
val start = 1
val end = 10
for (i <- start until end) {
println(i + " - hey")
}
}
}
6.10.4.3 循环守卫
for(i <- 1 to 3 if i != 2) {
print(i + " ")
}
object DemoTest007 {
def main(args: Array[String]): Unit = {
for (i <- 1 to 3 if i !=2){
println("num is = " + i)
}
}
}
6.10.4.4 引入变量
for(i <-1 to 3; j = 4 -i) {
print(j + " ")
}
object DemoTest007 {
def main(args: Array[String]): Unit = {
for(i <- 1 to 3 ; j = 4 - i){
println("num j is = " + j)
}
}
}
6.10.4.5 嵌套循环
for(i <-1 to 3; j <-1 to 3) {
println(" i =" + i + " j = " + j)
}
object DemoTest007 {
def main(args: Array[String]): Unit = {
for (i <- 1 to 3 ; j <- 1 to 5){
println("i is = " + i + " , " + "j is = " + j)
}
}
6.10.4.6 循环返回值
val res = for(i <-1 to 10) yield i
println(res)
object DemoTest007 {
def main(args: Array[String]): Unit = {
/**
* 对1 to 10 进行遍历
* yield i 将每次循环得到i放入到集合Vector中,并返回给res
*/
val res = for (i <- 1 to 10) yield {
if (i % 2 == 0) {
i
} else {
0
}
}
println(res)
}
}
6.10.4.7 使用花括号{}代替小括号()
for(i <-1 to 3; j = i * 2) {
println(" i= " + i + " j= " + j)
}
println("------------------------------------")
for {
i <-1 to 3
j = i * 2} {
println(" i= " + i + " j= " + j)
}
6.10.4.8 注意事项和细节说明
for (i <- Range(1,10,2)){
println(i)
}
for (i <- 1 to 10 if i % 2 == 1) {
println(i)
}

6.10.5 while 循环控制

while (循环条件) {
循环体(语句)
循环变量迭代
}
var i = 0
while (i < 10){
println(i)
i += 1
}

6.10.6 do..while 循环控制

do{
循环体(语句)
循环变量迭代
} while(循环条件)
var is = 0
do{
println(is)
is += 1
} while (is < 10)

6.10.7 多重循环控制

for (i <- 1 to 9){
for (j <- 1 to i){
printf("%d * %d = %d\t",j,i,j*i)
}
printf("\n")
}

6.10.8 while 循环中断

var n = 1
breakable {
while (n <= 20) {
n += 1
println ("n=" + n)
if (n == 18) {
// 使用函数式break函数中断循环
break()
}
}
}
println("ok")

6.11 Scala 函数式编程 基础

6.11.1 函数式编程内容

函数式编程基础 :
函数定义/声明
函数运行机制
递归 难点[最短路径,邮差问题,迷宫问题,回溯]
过程
过程

函数式编程高级 :
值函数(函数字面量)
高阶函数
闭包
应用函数
柯里化函数 抽象控制

6.11.2 函数式编程介绍

在学习Scala中将方法 / 函数 / 函数式编程和面向对象编程需要明确 :
1.在scala中方法和函数几乎可以等同(比如定义、使用、运行机制都一样),只是函数使用方式更加的灵活多样.
2.函数式编程是从编程方式(范式)角度来谈,可以这样理解 : 函数式编程把函数当做一等公民,充分利用函数、支持的函数多种使用方式.
3.面向对象编程是以对象为基础的编程方式.
4.在scala中函数式编程和面向对象编程融合在一起.

函数式编程思想
函数式编程是一种”编程范式” (programming paradigm)
它属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套函数调用.
函数式编程中,将函数也当做数据类型,因此可以接受函数当作输入(参数)和输出(返回值).
函数式编程中最重要的就是函数.

6.11.3 函数的定义

def 函数名([参数名: 参数类型], ...)[[: 返回值类型] =] {
语句...
return 返回值
}
object DemoTest009 {
def main(args: Array[String]): Unit = {
val sum: Any = getSum(10, 5, '+')
println("res is = " + sum)
}
// 定义函数/方法
def getSum(n1: Int, n2: Int, oper: Char) = {
if (oper == '+') {
n1 + n2
} else if (oper == '-') {
n1 - n2
} else {
null
}
}
}

6.11.4 函数注意事项

6.11.5 过程

6.11.6 惰性函数

6.11.6.1 Java实现懒加载
public class LazyDemo {
private String property;
// 属性也可能是一个数据库连接,文件等资源
public String getProperty() {
if (property == null) {
// 如果没有初始化过,那么进行初始化
property = initProperty();
}
return property;
}
private String initProperty() {
return "property";
}
}
6.11.6.2 惰性函数介绍
object DemoTest010 {
def main(args: Array[String]): Unit = {
lazy val res = sum(10, 20)
println("-----------------")
println("res=" + res)
def sum(n1: Int, n2: Int): Int = {
println("sum() 执行..")
return n1 + n2
}
}
}

6.11.7 异常

6.11.7.1 Java异常处理
public class JavaExceptionDemo01 {
public static void main(String[] args) {
try {
// 可疑代码
int i = 0;
int b = 10;
int c = b / i;
// 执行代码时,会抛出ArithmeticException异常
} catch (ArithmeticException ex) {
ex.printStackTrace();
} catch (Exception e) {
//java中不可以把返回大的异常写在前,否则报错!!
e.printStackTrace();
} finally {
// 最终要执行的代码
System.out.println("java finally");
}
System.out.println("ok~~~继续执行...");
}
}
6.11.7.2 Java异常处理注意点
6.11.7.3 Scala异常处理
object DemoTest011 {
def main(args: Array[String]): Unit = {
try {
val s = 10 / 0
} catch {
/**
* 在scala中只有一个catch
* 在catch中有多个case,每个case可以匹配一种异常case ex: ArithmeticException
* => 关键符号,表示后面是对该异常的处理代码块
* finally是最终执行
**/
case ex: ArithmeticException => println("Trapping arithmetic exception")
case ex: Exception => println("Capture exception")
} finally {
println("Scala finally")
}
println("Continue execution")
}
}
6.11.7.4 Scala异常处理小结
def main(args: Array[String]): Unit = {
f11()
}
//等同于NumberFormatException.class
@throws(classOf[NumberFormatException])
def f11() = {
"abc".toInt
}

6.12 Scala 面向对象编程 (基础部分)

6.12.1 类与对象

6.12.1.1 Scala语言是面向对象
object DemoTest013 {
def main(args: Array[String]): Unit = {
// 创建对象
val cat = new CatDemo
// 给对象属性赋值
cat.name = "kaka"
cat.age = 10
cat.colour = "black"
printf("Info : %s %d %s",cat.name,cat.age,cat.colour)
}
class CatDemo {
// 定义声明属性
var name: String = ""
var age: Int = _
var colour: String = ""
}
}
6.12.1.2 类和对象区别和联系
6.12.1.3 如何定义类
[修饰符] class 类名{
类体
}
6.12.1.4 属性
6.12.1.5 属性/成员变量
类型 _ 对应默认值
Byte / Short / Int / Long 0
Float / Double 0.0
String / 引用类型 null
Bollean false
6.12.1.6 属性高级部分
6.12.1.7 如何创建对象

6.12.2 方法

def 方法名(参数列表) [:返回值类型] = {
方法体
}

6.12.3 构造器

6.12.3.1 Java 构造器
[修饰符] 方法名(参数列表){
构造方法体
}
6.12.3.2 Scala 构造器
// 主构造器
class 类名(形参列表) {
// 类体
def this(形参列表) {
// 辅助构造器
}
def this(形参列表) {
// 辅助构造器可以有多个...
}
}
object DemoTest015 {
def main(args: Array[String]): Unit = {
// 初始化对象
val people = new People("tom", 18)
println(people)
}
// 创建类
class People(inName: String, inAge: Int) {
// 定义属性
var name: String = inName
var age: Int = inAge
// 重写toString方法
override def toString: String = {
"name = " + this.name + " , age = " + this.age
}
}
}
6.12.3.3 Scala构造器注意事项

6.12.4 属性高级

6.12.4.1 构造器参数
package com.geekparkhub.core.scala.demo
object DemoTest016 {
def main(args: Array[String]): Unit = {
val worker = new worker("tom")
worker.name
val worker2 = new worker2("jack")
worker2.inName
val worker3 = new worker3("macs")
worker3.inName = "tomcat"
println(worker3.inName)
}
class worker(inName: String) {
var name = inName
}
// 只读属性
class worker2(val inName: String) {
var name = inName
}
// 可读写属性
class worker3(var inName: String) {
var name = inName
}
}
6.12.4.2 Bean属性
object DemoTest017 {
def main(args: Array[String]): Unit = {
val car = new Car()
car.name = "G500"
println(car.name)
car.setName("G630")
println(car.getName)
}
class Car {
@BeanProperty var name: String = _
}
}

6.12.5 Scala对象创建流程分析

class Person {
var age: Short = 90
var name: String = _
def this(n: String, a: Int) {
this()
this.name = n
this.age = a
}
}
var p : Person = new Person("tom",18)

6.13 Scala 面向对象编程 (中级部分)

6.13.1 包

6.13.1.1 Java包三大作用
6.13.1.2 Java打包命令
package com.geekparkhub.core
6.13.1.3 Scala包基本介绍
6.13.1.4 Scala包快速入门
package com.geekparkhub.core.scala.package_flow.test001
class Test {
}
package com.geekparkhub.core.scala.package_flow.test002
class Test {
}
package com.geekparkhub.core.scala.package_flow
object PackageTest {
def main(args: Array[String]): Unit = {
val test001 = new com.geekparkhub.core.scala.package_flow.test001.Test
val test002 = new com.geekparkhub.core.scala.package_flow.test002.Test
println("test001 = " + test001 + "\n" + "test002 = " + test002)
}
}
test001 = com.geekparkhub.core.scala.package_flow.test001.Test@56cbfb61
test002 = com.geekparkhub.core.scala.package_flow.test002.Test@1134affc
6.13.1.5 Scala包特点概述
package 包名
6.13.1.6 Scala包命名
6.13.1.7 Scala自动引入常用包

java.lang.* / scala包 / Predef包

6.13.1.8 Scala包注意事项和使用细节
package com.geekparkhub.core.scala.package_flow
/**
* 创建test003包
*/
package test003 {
/**
* 创建类
*/
class Test {
// 定义属性
var name: String = _
// 定义函数
def info(name: String): Unit = {
println("name")
}
}
/**
* 创建对象
*/
object RunTest003 {
def main(args: Array[String]): Unit = {
// 实例化对象
val test003 = new Test()
// 调用对象函数
test003.info("tomcat")
println("test003 is = " + test003)
}
}
}
/**
* 创建包test004包
*/
package test004 {
/**
* 创建类
*/
class Test {
// 定义属性
var age: Int = _
// 定义函数
def infos(age: Int): Unit = {
println("age")
}
}
/**
* 创建对象
*/
object RunTest004 {
def main(args: Array[String]): Unit = {
val test004 = new Test()
test004.infos(18)
println("test004 is = " + test004)
}
}
}
6.13.1.9 包对象
package com.geekparkhub.core.scala.package_flow {
/**
* 创建包对象
*
* 每一个包都可以有一个包对象
* 包对象名称字需要和子包一致
* 在包对象中可以定义变量,方法
* 在包对象中定义的变量和方法,就可以在对应的包中使用
*/
package object scala {
// 定义属性
var age: Int = 18
// 定义函数
def info(): Unit = {
println("this info")
}
}
/**
* 创建包
*/
package scala {
// 创建类
class Test {
var name: String = _
}
// 创建主函数
object RunTest {
def main(args: Array[String]): Unit = {
// 调用包对象属性
println("age = " + age)
// 调用包对象函数
info()
}
}
}
}
6.13.1.9 包对象注意事项

6.13.2 包可见性问题

6.13.2.1 Java访问修饰符
6.13.2.2 Java访问修饰符使用注意事项
6.13.2.3 Scala 包可见性
package com.geekparkhub.core.scala.package_flow
object Visit {
def main(args: Array[String]): Unit = {
// 实例化对象
val test = new Test
// 调用info函数
test.info()
// 调用半生对象函数
Test.run(test)
}
// 创建半生类
class Test {
// 定义属性
var name: String = "tomcat"
// 定义私有属性
private var age: Int = 18
// 定义函数
def info(): Unit = {
println("name is " + name + " , " + "age is " + age)
}
}
// 创建半生对象
object Test {
def run(t: Test) {
println("name = " + t.name + " , age = " + t.age)
}
}
}
6.13.2.4 Scala 包可见性和访问修饰符使用
package com.geekparkhub.core.scala.package_flow
object Visit {
def main(args: Array[String]): Unit = {
// 实例化对象
val test = new Test
// 调用半生类属性
println("age is = " + test.age)
}
// 创建半生类
class Test {
// 定义属性
var name: String = "tomcat"
// 定义私有属性
private[package_flow] var age: Int = 18
// 定义函数
def info(): Unit = {
println("name is " + name + " , " + "age is " + age)
}
}
// 创建半生对象
object Test {
def run(t: Test) {
println("name = " + t.name + " , age = " + t.age)
}
}
}

6.13.3 包引入

6.13.3.1 Scala引入包基本介绍
6.13.3.2 Scala引入包细节和注意事项

6.13.4 面向对象编程 三大特征

6.13.5 面向对象编程方法 - 抽象

6.13.5.1 Scala 抽象快速入门案例
package com.geekparkhub.core.scala.demo
object AbstractBankDemo {
def main(args: Array[String]): Unit = {
// 创建 账户类
val account = new Account("4693803346873533", 5.0, "123456")
// 调用 查询余额函数
account.check_balances("4693803346873533", "123456")
// 调用 存款函数
account.deposit("4693803346873533","123456",1.1)
// 调用 取款函数
account.withDrawal("4693803346873533","123456",0.6)
}
/**
* 创建银行账户类
* 共有信息属性
* 账户/余额/密码/查询余额/取款/存款
*/
class Account(inAccount: String, inBalance: Double, inPassword: String) {
// 定义银行账户属性
private val account: String = inAccount
// 定义银行余额属性
private var balance: Double = inBalance
// 定义银行密码属性
private var password: String = inPassword
/**
* 定义银行查询余额函数
*
* @param account
* @param password
*/
def check_balances(account: String, password: String): Any = {
if (!this.account.equals(account)) {
println("Account error, please verify your account!")
return
}
if (!this.password.equals(password: String)) {
println("The password is wrong, please try again!")
return
}
printf("Account : %s\nBalance : %.2f\n", this.account, this.balance)
}
/**
* 定义银行取款函数
*
* @param password
* @param money
*/
def withDrawal(account: String, password: String, money: Double): Any = {
if (!this.account.equals(account)) {
println("Account error, please verify your account!")
return
}
if (!this.password.equals(password)) {
println("The password is wrong, please try again!")
return
}
if (this.balance < money) {
println("Failed withdrawal, insufficient current account balance!")
return
}
this.balance -= money
money
printf("Account : %s\nBalance : %.2f\n", this.account, this.balance)
}
/**
* 定义银行存款函数
*
* @param account
* @param password
* @param money
*/
def deposit(account: String, password: String, money: Double): Any = {
if (!this.account.equals(account)) {
println("Account error, please verify your account!")
return
}
if (!this.password.equals(password)) {
println("The password is wrong, please try again!")
return
}
this.balance += money
money
printf("Account : %s\nBalance : %.2f\n", this.account, this.balance)
}
}
}

6.13.6 面向对象编程 - 封装

6.13.6.1 封装介绍
6.13.6.2 封装理解和好处
6.13.6.3 如何体现封装
6.13.6.4 封装 实现步骤
6.13.6.5 Scala 封装快速入门案例
package com.geekparkhub.core.scala.demo
object AccountCore {
def main(args: Array[String]): Unit = {
val account = new Account_Flow("4693803346873533", "张三丰", 110, "123456")
account.setName("初始值")
account.setPassword("111111")
account.setBalance(100)
}
class Account_Flow(inAccount: String, inName: String, inBalance: Double, inPassword: String) {
// 定义银行账户属性
private val account: String = inAccount
// 定义银行用户名属性
private var name: String = ""
// 定义银行余额属性
private var balance: Double = inBalance
// 定义银行密码属性
private var password: String = inPassword
// 设置用户名限制
def setName(name: String): Unit = {
if (!this.inName.length.equals(name.length)) {
printf("初始化(%s)账户名设置必须大于三位,请重试!\n", this.account)
return
} else {
this.name = name
println("账户名设置成功!")
}
}
// 设置用户密码限制
def setPassword(password: String): Unit = {
if (!this.inPassword.length.equals(password.length)) {
printf("初始化(%s)账户密码必须设置大于6位数以上,请重试!\n", this.account)
return
}
this.password = password
println("账户密码设置成功!")
}
// 设置余额限制
def setBalance(balance: Double): Unit = {
if (this.inBalance.toDouble < balance) {
printf("当前(%s)账户余额不足:%.2f,请及时充值!\n", this.account,this.balance)
return
}
this.balance = balance
printf("当前(%s)账户余额%.2f", this.account, this.balance)
}
}
}
6.13.6.6 Scala 封装注意事项

6.13.7 面向对象编程 - 继承

6.13.7.1 Java继承
class 子类名extends 父类名{ 类体}
子类继承父类的属性和方法
6.13.7.2 继承基本介绍
6.13.7.3 Scala 继承基本语法
class 子类名 extends 父类名 { 类体 }
6.13.7.4 Scala 继承快速入门
package com.geekparkhub.core.scala.demo
object DemoTest018 {
def main(args: Array[String]): Unit = {
val teacher = new Teacher
teacher.name = "Tomcat"
teacher.work()
}
class Person {
var name: String = _
var age: Int = _
def info(): Unit = {
println("info : " + this.name)
}
}
class Teacher extends Person {
def work(): Unit = {
println(this.name + " Working!")
}
}
}
6.13.7.5 Scala继承优势
6.13.7.6 重写方法
package com.geekparkhub.core.scala.demo
object DemoTest018 {
def main(args: Array[String]): Unit = {
val teacher = new Teacher
teacher.name = "Tomcat"
teacher.info()
teacher.work()
}
class Person {
var name: String = "mac"
var age: Int = _
def info(): Unit = {
println("info : " + this.name)
}
}
class Teacher extends Person {
override def info() {
println("override info : "+ name)
super.info()
}
def work(): Unit = {
println(this.name + " Working!")
}
}
}
6.13.7.7 Scala中类型检查和转换
package com.geekparkhub.core.scala.demo
object DemoTest019 {
def main(args: Array[String]): Unit = {
// 使用ClassOf得到类名
println(classOf[String])
var str = "tomcat"
println(str.getClass.getName)
// 将子类引用给父类(向上转型,自动)
var base = new Base
var teacher = new Teacher
base = teacher
// 将父类的引用重新转成子类引用(多态),即向下转型
var teachers = base.asInstanceOf[Teacher]
teachers.work()
}
class Base {
var name: String = "mac"
var age: Int = _
def info(): Unit = {
println("info : " + this.name)
}
}
class Teacher extends Base {
override def info() {
println("override info : " + name)
super.info()
}
def work(): Unit = {
println(this.name + " Working!")
}
}
}
6.13.7.8 Scala超类构造
6.13.7.9 覆写字段
6.13.7.10 抽象类
package com.geekparkhub.core.scala.demo
object DemoTest022 {
def main(args: Array[String]): Unit = {
println("abstract")
}
// 抽象类
abstract class Base {
// 抽象字段
var name: String
// 抽象字段
var age: Int
// 普通属性
var color: String = "black"
// 抽象方法,不需要标记abstract
def cry()
}
}
6.13.7.11 Scala 抽象类使用注意事项
6.13.7.12 匿名子类
package com.geekparkhub.core.scala.demo
object DemoTest023 {
def main(args: Array[String]): Unit = {
val base = new Base {
override var name: String = "Mac"
override def cry(): Unit = {
println("Anonymous subclass\t" + name)
}
}
base.cry()
}
abstract class Base {
var name: String
def cry()
}
}
6.13.7.13 继承层级

6.14 Scala 面向对象编程 (高级特性)

6.14.1 静态属性和静态方法

package com.geekparkhub.core.scala.demo
object DemoTest024 {
def main(args: Array[String]): Unit = {
println(Base.sex)
Base.info()
}
// 半生类
class Base{
var name : String = _
}
// 半生对象
object Base{
var sex : Boolean = true
def info(): Unit ={
println("object ScalaPerson")
}
}
}

6.14.2 接口

6.14.2.1 Java 接口
6.14.2.2 Scala 接口

6.14.3 特质 (trait)

6.14.3.0 Scala 创建对象时有四种方式
6.14.3.1 trait 声明语法
trait 特质名{
trait
}
6.14.3.2 Scala trait 使用
没有父类
class 类名extends 特质1 with 特质2 with 特质3...
有父类
class 类名extends 父类with 特质1 with 特质2 with 特质3
6.14.3.3 特质快速入门
package com.geekparkhub.core.scala.demo
object DemoTest025 {
def main(args: Array[String]): Unit = {
val c = new C()
c.getConnect()
val f = new F()
f.getConnect()
}
// 定义特质
trait Base {
def getConnect()
}
// A类
class A {}
// B类
class B extends A {}
// C类
class C extends A with Base {
override def getConnect(): Unit = {
println("Connect to a new network")
}
}
// D类
class D {}
// E类
class E extends D {}
// F类
class F extends D with Base {
override def getConnect(): Unit = {
println("Connect to a new database")
}
}
}
6.14.3.3 特质trait说明
6.14.3.4 特质对象 动态混入
package com.geekparkhub.core.scala.demo
object DemoTest026 {
def main(args: Array[String]): Unit = {
val t1 = new T1 with Base
val t2 = new T2 with Base
val t1_ : T1_ with Base = new T1_ with Base {
override def t1(): Unit = {
println("The is t1")
}
}
t1_.t1()
t1.select(0)
t2.select(1)
}
trait Base {
def select(id: Int): Unit = {
println("id is = " + id)
}
}
abstract class T1 {}
abstract class T1_ {
def t1()
}
class T2 {}
}
6.14.3.5 叠加特质
package com.geekparkhub.core.scala.demo
object DemoTest027 {
def main(args: Array[String]): Unit = {
val base = new Base4 with Base2 with Base3
println(base)
base.info(1)
}
// 特质 Base类
trait Base {
println("Base")
def info(id: Int)
}
// 特质Base1继承Base
trait Base1 extends Base {
println("Base1")
def info(id: Int): Unit = {
println("insert = " + id)
}
}
// Base2继承Base1
trait Base2 extends Base1 {
println("Base2")
override def info(id: Int): Unit = {
println("-Base2-")
super.info(id)
}
}
trait Base3 extends Base2{
println("Base3")
override def info(id: Int): Unit = {
println("-Base3-")
super.info(id)
}
}
class Base4{}
}
package com.geekparkhub.core.scala.demo
object DemoTest028 {
def main(args: Array[String]): Unit = {
val b3 = new B3 with B2 with B1
b3.info(1)
}
trait Base {
def info(id: Int)
}
trait B1 extends Base {
abstract override def info(id: Int): Unit = {
println("B1")
super.info(id)
}
}
trait B2 extends Base {
def info(id: Int): Unit = {
println("B2")
}
}
class B3 {}
}
6.14.3.6 富接口
trait Operate {
def insert(id: Int)
def pageQuery(pageno: Int, pagesize: Int): Unit = {
println("Query")
}
}
6.14.3.7 特质中具体字段
6.14.3.8 特质中抽象字段
6.14.3.9 特质构造顺序
6.14.3.10 扩展类特质
// 特质扩展类
trait LoggedException extends Exception {
def log(): Unit = {
// 方法来自于Exception类
println(getMessage())
}
}
// 特质扩展类
trait LoggedException extends Exception {
def log(): Unit = {
// 方法来自于Exception类
println(getMessage())
}
}
/**
* 已经是Exception的子类了,所以可以重写方法
* 如果混入该特质的类,已经继承了另一个类(A类),则要求A类是特质超类的子类
* 否则就会出现了多继承现象,发生错误.
* @return
*/
class UnhappyException extends LoggedException {
override def getMessage = "错误消息!"
}
6.14.3.11 自身类型
trait Logger {
// 明确告诉编译器,,如果不是Exception就无法调用getMessage
this: Exception =>
def log(): Unit = {
println(getMessage)
}
}
class Console extends Exception with Logger {}

6.14.4 嵌套类

6.14.4.1 Scala 嵌套类使用 一
package com.geekparkhub.core.scala.demo
import com.geekparkhub.core.scala
object DemoTest029 {
def main(args: Array[String]): Unit = {
val test01: Test01 = new Test01
val test02: Test01 = new Test01
// 创建内部类
val test00 = new test01.Test002
val test001 = new test02.Test002
// 创建静态内部类实例
val static = new scala.demo.DemoTest029.Test01.Test004
}
// 外部类
class Test01 {
// 成员内部类
class Test002 {}
}
// 半生对象
object Test01 {
// 静态内部类
class Test004 {}
}
}
6.14.4.2 Scala 嵌套类使用 二
package com.geekparkhub.core.scala.demo
import com.geekparkhub.core.scala
object DemoTest029 {
def main(args: Array[String]): Unit = {
val test01: Test01 = new Test01
val test02: Test01 = new Test01
// 创建内部类
val test00 = new test01.Test002
val test001 = new test02.Test002
test00.info()
// 创建静态内部类实例
val static = new scala.demo.DemoTest029.Test01.Test004
}
// 外部类
class Test01 {
// 定义属性
var user = "root"
private var password = 78542
// 成员内部类
class Test002 {
def info() = {
// 访问方式 : 外部类名.this.属性名
println("user = " + Test01.this.user + "\npassword = " + Test01.this.password)
}
}
}
// 半生对象
object Test01 {
// 静态内部类
class Test004 {}
}
}
package com.geekparkhub.core.scala.demo
import com.geekparkhub.core.scala
object DemoTest029 {
def main(args: Array[String]): Unit = {
val test01: Test01 = new Test01
val test02: Test01 = new Test01
// 创建内部类
val test00 = new test01.Test002
val test001 = new test02.Test002
test00.info()
// 创建静态内部类实例
val static = new scala.demo.DemoTest029.Test01.Test004
}
// 外部类
class Test01 {
// 外部类别名
alias =>
// 成员内部类
class Test002 {
def info() = {
// 访问方式 : 外部类名.this.属性名
println("user = " + alias.user + "\npassword = " + alias.password)
}
}
// 定义属性
var user = "root"
private var password = 78542
}
// 半生对象
object Test01 {
// 静态内部类
class Test004 {}
}
}
6.14.4.3 类型投影
package com.geekparkhub.core.scala.demo
import com.geekparkhub.core.scala
object DemoTest029 {
def main(args: Array[String]): Unit = {
val test01: Test01 = new Test01
val test02: Test01 = new Test01
// 创建内部类
val test00 = new test01.Test002
val test001 = new test02.Test002
test00.info()
// 类型投影
test00.test(test00)
test00.test(test001)
test001.test(test00)
test001.test(test001)
// 创建静态内部类实例
val static = new scala.demo.DemoTest029.Test01.Test004
}
// 外部类
class Test01 {
// 外部类别名
alias =>
// 成员内部类
class Test002 {
def info() = {
// 访问方式 : 外部类名.this.属性名
println("user = " + alias.user + "\npassword = " + alias.password)
}
// 接受Test002实例
// 类型投影的作用就是屏蔽外部对象对内部类对象的影响
def test(ic: Test01#Test002): Unit = {
System.out.println("使用类型投影 " + ic)
}
}
// 定义属性
var user = "root"
private var password = 78542
}
// 半生对象
object Test01 {
// 静态内部类
class Test004 {}
}
}

6.15 Scala 隐式转换 & 隐式值

6.15.1 隐式函数快速入门

package com.geekparkhub.core.scala.demo
object DemoTest030 {
def main(args: Array[String]): Unit = {
// 定义隐式函数
implicit def d(d: Double): Int = {
d.toInt
}
val num: Int = 1.5
println("num = " + num)
}
}
package com.geekparkhub.core.scala.demo
object DemoTest030 {
def main(args: Array[String]): Unit = {
// 定义隐式函数
implicit def d(d: Double): Int = {
d.toInt
}
val num: Int = 1.5
println("num = " + num)
// 定义隐式函数
implicit def f(f: Float): Int = {
f.toInt
}
val num1: Int = 2.5f
println("num1 = " + num1)
}
}

6.15.2 隐式转换丰富类库功能

package com.geekparkhub.core.scala.demo
object DemoTest031 {
def main(args: Array[String]): Unit = {
val base = new BaseDB
base.select()
base.delete()
}
class BaseDB {
def select(): Unit = {
println("select")
}
}
class DB {
def delete(): Unit = {
println("delete")
}
}
// 隐式转换
implicit def addDelete(baseDB: BaseDB): DB = {
new DB
}
}

6.15.3 隐式值

package com.geekparkhub.core.scala.demo
object DemoTest032 {
def main(args: Array[String]): Unit = {
// 隐式值
implicit var name: String = "mac"
// 函数
def info(implicit name: String): Unit = {
println(name + "\tWorking!")
}
info
}
}

6.15.4 隐式类

package com.geekparkhub.core.scala.demo
object DemoTest033 {
def main(args: Array[String]): Unit = {
// 隐式类
implicit class DB(baseDB: BaseDB) {
def add(): String = {
baseDB + "DB"
}
}
val baseDB = new BaseDB
baseDB.select()
baseDB.add()
}
}
// 半生类
class BaseDB {
def select(): Unit = {
println("select")
}
}
6.15.4.1 隐式类使用特点

6.15.5 隐式转换时机

6.15.6 隐式解析机制

即编译器是如何查找到缺失信息的,解析具有以下两种规则 :

1.首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象).

2.如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找,类型的作用域是指与该类型相关联的全部伴生模块,一个隐式实体的类型T它的查找范围如下(第二种情况范围广且复杂在使用时,应当尽量避免出现).

3.如果T被定义为T with A with B with C,那么A,B,C都是T的部分,在T的隐式解析过程中,它们的半生对象都会被搜索.

4.如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分,比如List[String]的隐式搜索会搜索List的半生对象和String的半生对象.

5.如果T是一个单例类型p.T,即T是属于某个p对象内,那么这个p对象也会被搜索.

6.如果T是个类型注入S#T,那么S和T都会被搜索.

6.15.7 隐式转换使用陷阱

package com.geekparkhub.core.scala.demo
object DemoTest034 {
def main(args: Array[String]): Unit = {
// 隐式函数
implicit def test(d: Double): Int = {
d.toInt
// 错误示范 : 隐式操作递归调用,不能嵌套使用
val num: Int = 1.9
}
// 正确示范
val num: Int = 2.0
}
}

6.16 Scala 数据结构 (上) - 集合

6.16.1 数据结构特点

6.16.1 Scala集合基本介绍

1.Scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问.
不可变集合:scala.collection.immutable
可变集合:scala.collection.mutable

2.Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本.

3.Scala的集合有三大类 : 序列Seq(有序,Linear Seq)、集Set、映射Map[key->value],所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型.

enter image description here

6.16.2 可变集合和不可变集合

1.不可变集合 : Scala不可变集合就是这个集合本身不能动态变化,(类似java的数组,是不可以动态增长).

2.可变集合:可变集合就是这个集合本身可以动态变化,(比如:ArrayList,是可以动态增长).

6.16.2 不可变集合

enter image description here

6.16.3 可变集合

enter image description here

6.16.4 数组-定长数组(声明泛型)

6.16.4.1 第一种方式定义数组
package com.geekparkhub.core.scala.collection
object CollectionFlow001 {
def main(args: Array[String]): Unit = {
// 创建Array对象
val array001 = new Array[Int](4)
println("array001 数组长度 = "+ array001.length)
array001(0) = 10
array001(3) = 11
for (index <- 0 until array001.length) {
printf("array001[%d] = %s", index, array001(index) + "\n")
}
}
}
6.16.4.2 第二种方式定义数组
package com.geekparkhub.core.scala.collection
object CollectionFlow002 {
def main(args: Array[String]): Unit = {
val array002 = Array(1, 3, "xyz")
println("array002 数组长度 = " + array002.length)
array002(0) = "tz"
array002(1) = "zz"
for (index <- 0 until array002.length) {
printf("array002[%d] = %s", index, array002(index) + "\n")
}
}
}

6.16.5 数组-变长数组(声明泛型)

package com.geekparkhub.core.scala.collection
import scala.collection.mutable.ArrayBuffer
object CollectionFlow003 {
def main(args: Array[String]): Unit = {
// Create ArrayBuffer
val array003 = ArrayBuffer[Int](2, 4, 6)
// array003 下标1元素数值
println("array003(1) = " + array003(1))
// 循环遍历array003所有下标元素数值
for (i <- array003) {
println("array003 所有下标元素数值 = " + i)
}
// array003数组长度以及array003哈希值
println("array003数组长度 = " + array003.length)
println("array003.hashCode() = " + array003.hashCode())
// 追加元素array003及array003哈希值
array003.append(1, 3, 5)
println("array003.hashCode() = " + array003.hashCode())
// 修改array003 下标1元素数值
array003(1) = 87
for (i <- array003) {
println("array003 修改后所有下标元素数值 = " + i)
}
// 删除array003 下标0元素数值
array003.remove(0)
for (i <- array003) {
println("array003 删除后所有下标元素数值 = " + i)
}
println("array003删除后数组长度 = " + array003.length)
}
}
6.16.5.1 变长数组分析总结

ArrayBuffer是变长数组,类似java的ArrayList
val arr2 = ArrayBuffer<a href="">Int</a>也是使用的apply方法构建对象.
def append(elems: A*) { appendAll(elems) } 接收的是可变参数.
每append一次,arr在底层会重新分配空间,进行扩容,arr2的内存地址会发生变化,也就成为新的ArrayBuffer.

6.16.5.2 定长数组与变长数组 转换
package com.geekparkhub.core.scala.collection
import scala.collection.mutable.ArrayBuffer
object CollectionFlow004 {
def main(args: Array[String]): Unit = {
// Create ArrayBuffer
val array004 = ArrayBuffer[Int]()
array004.append(1, 3, 5)
println(array004)
// 可变数组转定长数组
val newArray = array004.toArray
println("newArray = " + newArray)
// 定长数组转可变数组
val newArray2 = newArray.toBuffer
newArray2.append(246)
println("newArray2 = " + newArray2)
}
}
6.16.5.3 多维数组定义和使用
// 二维数组中有三个一维数组,每个一维数组中有四个元素,可以理解为三行四列
Array.ofDim[Double](3,4)
package com.geekparkhub.core.scala.collection
object CollectionFlow005 {
def main(args: Array[String]): Unit = {
// 创建二维数组
val array005 = Array.ofDim[Int](3, 4)
// 双层循环遍历二维数组元素
// 遍历一维数组元素
for (i <- array005) {
// 对一维数组元素结果遍历二维数组元素
for (j <- i) {
printf(j + "\t")
}
println()
}
// 指定访问二维数字元素
println("array005(1)(1) = " + array005(1)(1))
// 修改二维数字元素
array005(1)(1) = 100
for (i <- array005) {
// 对一维数组元素结果遍历二维数组元素
for (j <- i) {
printf(j + "\t")
}
println()
}
for (i <- 0 to array005.length - 1) {
for (j <- 0 to array005(i).length - 1) {
printf("array005[%d][%d]=%d\t", i, j, array005(i)(j))
}
println()
}
}
}

6.16.6 数组-Scala数组与JavaList互转

6.16.6.1 Scala数组转JavaList
package com.geekparkhub.core.scala.collection
import scala.collection.mutable.ArrayBuffer
object CollectionFlow006 {
def main(args: Array[String]): Unit = {
var array006 = ArrayBuffer("2", "4", "6")
import scala.collection.JavaConversions.bufferAsJavaList
val builder = new ProcessBuilder(array006)
val list = builder.command()
println(list)
}
}
6.16.6.2 JavaList转Scala数组(mutable.Buffer)
package com.geekparkhub.core.scala.collection
import scala.collection.mutable.ArrayBuffer
object CollectionFlow006 {
def main(args: Array[String]): Unit = {
var array006 = ArrayBuffer("2", "4", "6")
import scala.collection.JavaConversions.bufferAsJavaList
val builder = new ProcessBuilder(array006)
val list = builder.command()
println(list)
println("=====================")
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable
val scalaArray: mutable.Buffer[String] = list
scalaArray.append("mac")
scalaArray.remove(0)
println(scalaArray)
}
}

6.16.7 元组Tuple-元组

6.16.7.1 基本介绍

元组也是可以理解为一个容器,可以存放各种相同或不同类型数据.

元组中最大只能有22个元素,简单的说就是将多个无关数据封装为一个整体称为元组,最多特点灵活,对数据没有过多约束.

6.16.7.2 元组创建
package com.geekparkhub.core.scala.collection
object CollectionFlow007 {
def main(args: Array[String]): Unit = {
// 创建 元祖
val tuple1 = (2, 4, 6, "mac", 8)
println("tuple1 = " + tuple1)
}
}
package com.geekparkhub.core.scala.collection;
public final class CollectionFlow007$
{
public static final CollectionFlow007$ MODULE$;
private CollectionFlow007$() { MODULE$ = this; }
static {
}
public void main(String[] args) { // Byte code:
// 0: new scala/Tuple5
// 3: dup
// 4: iconst_2
// 5: invokestatic boxToInteger : (I)Ljava/lang/Integer;
// 8: iconst_4
// 9: invokestatic boxToInteger : (I)Ljava/lang/Integer;
// 12: bipush #6
// 14: invokestatic boxToInteger : (I)Ljava/lang/Integer;
// 17: ldc 'mac'
// 19: bipush #8
// 21: invokestatic boxToInteger : (I)Ljava/lang/Integer;
// 24: invokespecial <init> : (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
// 27: astore_2
// 28: getstatic scala/Predef$.MODULE$ : Lscala/Predef$;
// 31: aload_2
// 32: invokevirtual println : (Ljava/lang/Object;)V
// 35: return
// Line number table:
// Java source line number -> byte code offset
// #6 -> 0
// #7 -> 28
// Local variable table:
// start length slot name descriptor
// 0 36 0 this Lcom/geekparkhub/core/scala/collection/CollectionFlow007$;
// 0 36 1 args [Ljava/lang/String;
// 28 7 2 tuple1 Lscala/Tuple5; }
}

6.16.8 元组Tuple-元组数据访问

package com.geekparkhub.core.scala.collection
object CollectionFlow007 {
def main(args: Array[String]): Unit = {
// 创建 元祖
val tuple1 = (2, 4, 6, "mac", 8)
println("tuple1 = " + tuple1)
// 访问元祖第一个元素,从_1开始
println("tuple1._1 = " + tuple1._1)
// 访问元祖第一个元素,从0开始
println("tuple1.productElement(0) = " + tuple1.productElement(0))
}
}

6.16.9 元组Tuple-元组数据遍历

package com.geekparkhub.core.scala.collection
object CollectionFlow007 {
def main(args: Array[String]): Unit = {
// 创建 元祖
val tuple1 = (2, 4, 6, "mac", 8)
println("tuple1 = " + tuple1)
// 遍历元祖
for (i <- tuple1.productIterator){
println("tuple1 = " + i)
}
}
}

6.16.10 列表List-创建List

package com.geekparkhub.core.scala.collection
object CollectionFlow008 {
def main(args: Array[String]): Unit = {
// 创建List集合
val list001 = List(1, 3, 5)
println("list001 = " + list001)
// 创建List空集合
val list002 = Nil
println("list002 = " + list002)
}
}

6.16.11 列表List-访问List元素

package com.geekparkhub.core.scala.collection
object CollectionFlow008 {
def main(args: Array[String]): Unit = {
// 创建List集合
val list001 = List(1, 3, 5)
println("list001 = " + list001)
// 创建List空集合
val list002 = Nil
println("list002 = " + list002)
// 访问List集合
val value0: Int = list001(0)
val value1: Int = list001(1)
val value2: Int = list001(2)
println("value0 = " + value0 + "\n" + "value1 = " + value1 + "\n" + "value2 = " + value2)
}
}

6.16.12 列表List-元素追加

6.16.12.1 方式1-在列表最后增加数据
package com.geekparkhub.core.scala.collection
object CollectionFlow008 {
def main(args: Array[String]): Unit = {
// 创建List集合
val list001 = List(1, 3, 5)
println("list001 = " + list001)
// 访问List集合
val value0: Int = list001(0)
val value1: Int = list001(1)
val value2: Int = list001(2)
println("value0 = " + value0 + "\n" + "value1 = " + value1 + "\n" + "value2 = " + value2)
/**
* 在List集合后追加数据
* :+ 运算符表示在列表最后增加数据
*/
val list003 = list001 :+ 9
println("list001 = " + list001)
println("list003 = " + list003)
}
}
6.16.12.2 方式2-在列表最前面增加数据
package com.geekparkhub.core.scala.collection
object CollectionFlow008 {
def main(args: Array[String]): Unit = {
// 创建List集合
val list001 = List(1, 3, 5)
println("list001 = " + list001)
// 访问List集合
val value0: Int = list001(0)
val value1: Int = list001(1)
val value2: Int = list001(2)
println("value0 = " + value0 + "\n" + "value1 = " + value1 + "\n" + "value2 = " + value2)
/**
* 在List集合前追加数据
* +: 运算符表示在列表最前增加数据
*/
val list004 = 0 +: list001
println("list001 = " + list001)
println("list004 = " + list004)
}
}
6.16.12.3 方式3-在列表最后增加数据
package com.geekparkhub.core.scala.collection
object CollectionFlow008 {
def main(args: Array[String]): Unit = {
// 创建List集合
val list001 = List(1, 3, 5)
println("list001 = " + list001)
// 访问List集合
val value0: Int = list001(0)
val value1: Int = list001(1)
val value2: Int = list001(2)
println("value0 = " + value0 + "\n" + "value1 = " + value1 + "\n" + "value2 = " + value2)
/**
* 在List集合后追加数据
* :: 运算符,向集合中新建集合添加元素
*/
val list005 = List(1, 2, 3, "mac")
val list006 = 4 :: 5 :: 6 :: list005 :: Nil
println("list006 = " + list006)
/**
* 在List集合后追加数据
* ::: 运算符,将集合中每一个元素加入到集合中
*/
val list007 = List(1, 2, 3, "mac")
val list008 = 4 :: 5 :: 6 :: list005 ::: Nil
println("list008 = " + list008)
}
}
6.16.12.3 List集合测试题
package com.geekparkhub.core.scala.collection
object CollectionFlow009 {
def main(args: Array[String]): Unit = {
val testFlow = new TestFlow
testFlow.collectionFunction001()
testFlow.collectionFunction002()
testFlow.collectionFunction003()
testFlow.collectionFunction004()
}
// 创建半生类
class TestFlow {
// 集合函数001
def collectionFunction001(): Unit = {
val list001 = List(1, 2, 3, "tomcat")
val list002 = 4 :: 5 :: list001
println("list002 = " + list002)
}
// 集合函数002
def collectionFunction002(): Unit = {
val list001 = List(1, 2, 3, "tomcat")
// 程序错误,9不是集合对象,最右侧应该存放集合对象
val list002 = 4 :: 5 :: list001 :: 9
println("list002 = " + list002)
}
// 集合函数003
def collectionFunction003(): Unit = {
val list001 = List(1, 2, 3, "tomcat")
// 程序错误,运行顺序从右向左执行,6不是集合类型
val list002 = 4 :: 5 :: 6 ::: list001 ::: Nil
println("list002 = " + list002)
}
// 集合函数004
def collectionFunction004(): Unit = {
val list001 = List(1, 2, 3, "tomcat")
val list002 = 4 :: 5 :: list001 ::: list001 ::: Nil
println("list002 = " + list002)
}
}
}

6.16.13 列表ListBuffer

package com.geekparkhub.core.scala.collection
import scala.collection.mutable.ListBuffer
object CollectionFlow010 {
def main(args: Array[String]): Unit = {
// 创建listBuffer
val listBuffer001 = ListBuffer[Int](1, 2, 3)
println("listBuffer001(2) = " + listBuffer001(2))
for (i <- listBuffer001) {
println("i = " + i)
}
// 创建listBuffer
val listBuffer002 = new ListBuffer[Int]
// 添加单个元素
listBuffer002 += 4
listBuffer002.append(5)
println("listBuffer002 = " + listBuffer002)
// 将listBuffer002集合元素(4,5,)添加到另一个listBuffer001集合元素(1,2,3)
listBuffer001 ++= listBuffer002
println("listBuffer001 = " + listBuffer001)
//将listBuffer001集合元素与listBuffer002集合元素相加
val listBuffer003 = listBuffer001 ++ listBuffer002
println("listBuffer003 = " + listBuffer003)
// 在listBuffer001集合追加元素
val listBuffer004 = listBuffer001 :+ 6
println("listBuffer004 = " + listBuffer004)
// 指定删除集合元素
println("listBuffer002 = " + listBuffer002)
// 删除将下标为1的元素
listBuffer002.remove(1)
for (i <- listBuffer002) {
println("i = " + i)
}
}
}

6.16.14 队列Queue

6.16.14.1 队列说明

6.16.15 队列Queue-队列创建

package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow011 {
def main(args: Array[String]): Unit = {
// 创建Queue队列对象
val queue = new mutable.Queue[Int]()
println("queue = " + queue)
}
}

6.16.16 队列Queue-队列元素追加数据

package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow011 {
def main(args: Array[String]): Unit = {
// 创建Queue队列对象
val queue = new mutable.Queue[Any]()
println("queue = " + queue)
// 向Queue队列追加元素
queue += 1
println("queue = " + queue)
// 元素数值默认添加到Queue队列后
queue ++= List(3, 5, 7)
println("queue = " + queue)
// 将list集合作为一个元素追加到Queue队列,且类Queue队列类型必须设置为Any类型
queue += List(9, 11, 13)
println("queue = " + queue)
}
}

6.16.17 队列Queue-删除和加入队列元素

package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow011 {
def main(args: Array[String]): Unit = {
// 创建Queue队列对象
val queue = new mutable.Queue[Any]()
println("queue = " + queue)
// 向Queue队列追加元素
queue += 1
println("queue = " + queue)
// 元素数值默认添加到Queue队列后
queue ++= List(3, 5, 7)
println("queue = " + queue)
// 将list集合作为一个元素追加到Queue队列,且Queue队列类型必须设置为Any类型
queue += List(9, 11, 13)
println("queue = " + queue)
// 出队列,从队列头部中删除元素
val queueElement = queue.dequeue()
println("queueElement = " + queueElement + " | queue = "+queue)
// 入队列,默认在队列尾部加入元素
queue.enqueue(15,17,19)
println("queue = " + queue)
}
}

6.16.18 队列Queue-返回队列元素

package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow011 {
def main(args: Array[String]): Unit = {
// 创建Queue队列对象
val queue = new mutable.Queue[Any]()
println("queue = " + queue)
// 向Queue队列追加元素
queue += 1
println("queue = " + queue)
// 元素数值默认添加到Queue队列后
queue ++= List(3, 5, 7)
println("queue = " + queue)
// 将list集合作为一个元素追加到Queue队列,且Queue队列类型必须设置为Any类型
queue += List(9, 11, 13)
println("queue = " + queue)
// 出队列,从队列头部中删除元素
val queueElement = queue.dequeue()
println("queueElement = " + queueElement + " | queue = " + queue)
// 入队列,默认在队列尾部加入元素
queue.enqueue(15, 17, 19)
println("queue = " + queue)
/**
* 返回Queue队列元素
*/
// 获取队列第一个元素
println("head = " + queue.head)
// 获取队列最后一个元素
println("last = " + queue.last)
// 取出队尾数据,返回除了第一个以外剩余元素,可以级联使用
println("tail = " + queue.tail)
println("tail.tail.tail = " + queue.tail.tail.tail)
}
}

6.16.19 映射Map

6.16.19.1 Java Map
package com.geekparkhub.core.scala.collection;
import java.util.HashMap;
public class JavaHashMap {
public static void main(String[] args) {
HashMap<String, Integer> hm = new HashMap();
hm.put("node1", 100);
hm.put("node2", 200);
hm.put("node3", 300);
hm.put("node4", 400);
hm.put("node1", 500);
System.out.println(hm);
System.out.println(hm.get("node2"));
}
}
6.16.19.2 Scala Map

6.16.20 映射Map-四种Map构建方式

6.16.20.1 方式1-构造不可变映射
package com.geekparkhub.core.scala.collection
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建不可变Map对象
val map = Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map = " + map)
}
}
6.16.20.2 方式2-构造可变映射
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建不可变Map对象
val map = Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map = " + map)
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
}
}
6.16.20.3 方式3-创建空Map映射
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建不可变Map对象
val map = Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map = " + map)
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 创建空Map对象
val map3 = new mutable.HashMap[String, Int]
println("map3 = " + map3)
}
}
6.16.20.4 方式4-对偶元组
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建不可变Map对象
val map = Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map = " + map)
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 创建空Map对象
val map3 = new mutable.HashMap[String, Int]
println("map3 = " + map3)
// 创建对偶元组
val map4 = mutable.Map(("Hadoop", 1), ("Scala", 2), ("Spark", 3), ("Flink", 4))
println("map4 = " + map4)
}
}

6.16.21 映射Map-四种Map取值方式

6.16.21.1 方式1-使用map(key)
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// map(key)取值
println("map2(\"Hadoop\") = " + map2("Hadoop"))
}
}
6.16.21.2 方式2-使用contains方法检查key是否存在
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 使用contains方法检查key是否存在
if (map2.contains("Sparks")) {
println("Key exists , Value = " + map2("Sparks"))
} else {
println("Key does not exist :)")
}
}
}
6.16.21.3 方式3-使用map.get(key).get取值
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
/**
* 使用map.get(key).get取值
* 如果key存在,则就会返回Some(value),通过Some(value).get取出元素
* 如果key不存在,则就会返回None
*/
println("map2.get(\"Spark\") = " + map2.get("Spark"))
println("map2.get(\"Spark\").get = " + map2.get("Spark").get)
println("map2.get(\"Sparks\").get = " + map2.get("Sparks").get)
}
}
6.16.21.4 使用map.getOrElse()取值
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 使用map.getOrElse()取值
println("map2.getOrElse = " + map2.getOrElse("Spark", "Defaults"))
println("map2.getOrElse = " + map2.getOrElse("Sparks", "Defaults = 5"))
}
}
6.16.21.5 如何选择取值方式

1.如果确定map有key时,则应当使用map(key),因为取值速度快.

2.如果不能确定map是否有key时,而且有不同业务逻辑,则使用map.contains()先判断在加入逻辑.

3.如果只是简单希望得到一个值,则使用map.getOrElse(“ip”,”127.0.0.1”)即可.

6.16.22 映射Map-对Map修改/添加/删除

6.16.22.1 更新map元素
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 更新map元素
map2("Flink") = 5
println("map2 = "+ map2)
map2("Storm") = 6
println("map2 = "+ map2)
}
}
6.16.22.2 添加map元素
6.16.22.2.1 添加单个map元素
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 添加单个map元素
map2 += ("Hive" -> 7)
map2 += ("Flume" -> 8)
println("map2 = " + map2)
}
}
6.16.22.2.1 添加多个map元素
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 添加多个map元素
map2 += ("Kafka" -> 9, "Sqoop" -> 10)
println("map2 = " + map2)
val map5 = map2 + ("Oozie" -> 11, "Hbase" -> 12)
println("map5 = " + map5)
}
}
6.16.22.3 删除map元素
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// 删除map元素
map2 -= ("Hadoop","Scala","HashMap")
println("map2 = " + map2)
}
}

6.16.23 映射Map-map遍历

说明 :
每遍历一次,返回元素是Tuple2,取出时可以按照元组方式来取值.

对map元素(元组Tuple2对象)进行遍历方式很多种 : 方式如下

map遍历实例

package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow012 {
def main(args: Array[String]): Unit = {
// 创建可变Map对象
val map2 = mutable.Map("Hadoop" -> 1, "Scala" -> 2, "Spark" -> 3, "Flink" -> 4)
println("map2 = " + map2)
// map遍历
println("--------------------------------------")
for ((key, value) <- map2) println(key + " is Mapped To " + value)
println("--------------------------------------")
for (value <- map2.keys) println("keys = " + value)
println("--------------------------------------")
for (value <- map2.values) println("values = " + value)
println("--------------------------------------")
for (value <- map2) println(value + " | key = " + value._1 + " | value = " + value._2)
println("--------------------------------------")
}
}

6.16.24 集合Set

6.16.24.1 集合Set-创建
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow013 {
def main(args: Array[String]): Unit = {
// 创建不可变Set对象
val set01 = Set(2, 4, 6)
println("set01 = " + set01)
// 创建可变Set对象
val set02 = mutable.Set(1, 3, 5, "mac")
println("set02 = " + set02)
}
}
6.16.24.2 集合Set-可变集合元素添加/删除
6.16.24.2.1 可变集合元素添加
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow013 {
def main(args: Array[String]): Unit = {
// 创建不可变Set对象
val set01 = Set(2, 4, 6)
println("set01 = " + set01)
// 创建可变Set对象
val set02 = mutable.Set(1, 3, 5, "mac")
println("set02 = " + set02)
// 添加元素
set02.add(7)
set02 += 9
set02.+=("pro")
println("set02 = " + set02)
}
}
6.16.24.2.2 可变集合元素删除
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow013 {
def main(args: Array[String]): Unit = {
// 创建不可变Set对象
val set01 = Set(2, 4, 6)
println("set01 = " + set01)
// 创建可变Set对象
val set02 = mutable.Set(1, 3, 5, "mac")
println("set02 = " + set02)
// 添加元素
set02.add(7)
set02 += 9
set02.+=("pro")
println("set02 = " + set02)
// 删除元素
set02.-= ("pro")
set02.remove(9)
println("set02 = " + set02)
}
}
6.16.24.3 集合Set-集合遍历
package com.geekparkhub.core.scala.collection
import scala.collection.mutable
object CollectionFlow013 {
def main(args: Array[String]): Unit = {
// 创建不可变Set对象
val set01 = Set(2, 4, 6)
println("set01 = " + set01)
// 创建可变Set对象
val set02 = mutable.Set(1, 3, 5, "mac")
println("set02 = " + set02)
// 添加元素
set02.add(7)
set02 += 9
set02.+=("pro")
println("set02 = " + set02)
// 删除元素
set02.-=("pro")
set02.remove(9)
println("set02 = " + set02)
// 遍历集合
for (i <- set02) {
println("for set002 = " + i)
}
}
}

🔒 尚未解锁 正在探索中… 尽情期待 Blog更新! 🔒

6.17 Scala 数据结构 (下) - 集合操作

6.18 Scala 模式匹配

6.19 Scala 函数式编程 高级

6.20 Scala 使用递归方式去思考编程

7. 修仙之道 技术架构迭代 登峰造极之势

Alt text


💡如何对该开源文档进行贡献💡

  1. Blog内容大多是手敲,所以难免会有笔误,你可以帮我找错别字。

  2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。

  3. 现有的知识点难免存在不完善或者错误,所以你可以对已有知识点的修改/补充。

  4. 💡欢迎贡献各领域开源野生Blog&笔记&文章&片段&分享&创想&OpenSource Project&Code&Code Review

  5. 🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈 issues: geekparkhub.github.io/issues 🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈🙈

希望每一篇文章都能够对读者们提供帮助与提升,这乃是每一位笔者的初衷


💌感谢您的阅读 欢迎您的留言与建议💌

捐助 项目的发展离不开你的支持,请开发者喝杯☕Coffee☕吧!

enter image description here

致谢

捐助时请备注 UserName

ID UserName Donation Money Consume
1 Object WeChatPay 5RMB 一杯可乐
2 泰迪熊看月亮 AliPay 20RMB 一杯咖啡
3 修仙道长 WeChatPay 10RMB 两杯可乐

License 开源协议

Apache License Version 2.0